﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Configuration;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace XmlDataCommunication
{
    public abstract class GeneralFunctions
    {
        public static DataTable GetDataTableByXmlNodes(XmlNodeList nodes)
        {
            if (nodes.Count == 0) return new DataTable();
            DataTable dt = CreateDataTableSchema(nodes[0]);
            foreach (XmlNode item in nodes)
            {
                DataRow row = dt.NewRow();
                foreach (XmlNode childNode in item.ChildNodes)
                {
                    row[childNode.Name] = childNode.InnerText;
                }
                dt.Rows.Add(row);
            }
            return dt;
        }

        public static DataRow GetDataRowByXmlNode(XmlNode node)
        {
            if (node == null) return null;
            DataTable dt = CreateDataTableSchema(node);
            DataRow row = dt.NewRow();
            foreach (XmlNode item in node.ChildNodes)
            {
                row[item.Name] = item.InnerText;
            }
            dt.Rows.Add(row);
            return dt.Rows[0];
        }

        public static DataTable CreateDataTableSchema(XmlNode node)
        {
            DataTable dt = new DataTable();
            if (node == null) return dt;
            foreach (XmlNode item in node.ChildNodes)
            {
                dt.Columns.Add(new DataColumn(item.Name, typeof(string)));
            }
            return dt;
        }

        public static XmlDocument GetXmlDocument()
        {
            XmlDocument doc = new XmlDocument();
            string filePath = AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings["DataFilePath"];
            doc.Load(filePath);
            return doc;
        }

        public static void SaveXmlDocument(XmlDocument doc)
        {
            string filePath = AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings["DataFilePath"];
            doc.Save(filePath);
        }

        public static XmlDocument GetLinePositionXmlDocument()
        {
            XmlDocument doc = new XmlDocument();
            string filePath = AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings["LinePositionFilePath"];
            doc.Load(filePath);
            return doc;
        }

        public static void SaveLinePositionXmlDocument(XmlDocument doc)
        {
            string filePath = AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings["LinePositionFilePath"];
            doc.Save(filePath);
        }

        public static XmlNode CreateRecordInTable(XmlDocument doc, string tableName, List<string> columnNames)
        {
            XmlNode node = doc.SelectSingleNode("//" + tableName);
            XmlNode recordNode = doc.CreateElement("Record");
            node.AppendChild(recordNode);
            foreach (var item in columnNames)
            {
                XmlNode columnNode = doc.CreateElement(item);
                recordNode.AppendChild(columnNode);
            }
            return recordNode;
        }

        public static XmlNode CreateRecordInTable(XmlDocument doc, string tableName, Dictionary<string, string> columnNamesAndValues)
        {
            XmlNode node = doc.SelectSingleNode("//" + tableName);

            if (node == null)
            {
                if (!doc.HasChildNodes)
                {
                    XmlNode nodeRoot = doc.CreateElement("Tables");

                    doc.ImportNode(nodeRoot, false);
                }

                node = doc.CreateElement(tableName);
                doc.ChildNodes[1].AppendChild(node);
            }

            XmlNode recordNode = doc.CreateElement("Record");
            node.AppendChild(recordNode);
            foreach (var item in columnNamesAndValues.Keys)
            {
                XmlNode columnNode = doc.CreateElement(item);
                columnNode.InnerText = columnNamesAndValues[item];
                recordNode.AppendChild(columnNode);
            }
            return recordNode;
        }

        public static XmlNode RemoveAllRecordsInTable(XmlDocument doc, string tableName)
        {
            XmlNode node = doc.SelectSingleNode("//" + tableName);

            if (node != null)
            {
                node.RemoveAll();
            }

            return node;
        }
    }

    [Serializable]
    public class SerializableXmlDocument
    {
        private XmlDocument doc;
        public SerializableXmlDocument(XmlDocument doc)
        {
            this.doc = doc;
        }

        public XmlDocument Document
        {
            get { return doc; }
            set { doc = value; }
        }

    }
}
